/* FileExplorer.java
 * Author: liuex
 * 2007-12-20 ����09:27:21
 *
 * Note: 
 */
package org.lex.explorer.file;

import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.Collections;

import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter.SortKey;
import javax.swing.SortOrder;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableRowSorter;

import org.lex.explorer.AbstractExplorer;
import org.lex.swing.Swings;
import org.lex.swing.table.DateRenderer;
import org.lex.swing.table.DefaultRenderer;
import org.lex.swing.table.TableHelper;
import org.lex.utils.Comparators;
import org.lex.utils.SystemProperties;

public class FileExplorer extends AbstractExplorer {
	private File directory = null;
	private JTable table = null;
	private FileTableModel tableModel = null;
	private TablePopupMenu popupMenu = null;

	public static void main(String[] args) {
		Swings.show(new FileExplorer(), false);
	}

	public FileExplorer() {
		this(new File(SystemProperties.userHome()));
	}

	public FileExplorer(String dir) {
		this(new File(dir));
	}

	public FileExplorer(File directory) {
		super();
		this.directory = directory;
		// this.fv = CacheFileView.wrap( FileSystem.getLocalFileView() );
		this.initialize();
	}

	@Override
	public File getDirectory() {
		return this.directory;
	}

	@Override
	public void setDirectory(File directory, boolean fireEvent) {
		log.trace("change to directory: " + directory.toString());
		File old = this.directory;
		this.directory = directory;
		this.getTableModel().setDirectory(directory);
		if (true == fireEvent)
			this.fireDirectoryChange(old, directory);
	}

	public File getSelectedFile() {
		JTable table = this.getTable();
		int row = table.getSelectedRow();
		if (row < 0)
			return null;
		row = table.convertRowIndexToModel(row);
		return getTableModel().getFile(row);
	}

	public int getSelectedItemsCount() {
		return this.getTable().getSelectedRowCount();
	}

	public File[] getSelectedFiles() {
		JTable table = this.getTable();
		int[] rows = table.getSelectedRows();
		if (0 == rows.length)
			return new File[0];
		File[] files = new File[rows.length];
		FileTableModel model = this.getTableModel();
		for (int i = 0; i < rows.length; i++) {
			rows[i] = table.convertRowIndexToModel(rows[i]);
			files[i] = model.getFile(rows[i]);
		}
		return files;
	}

	public TablePopupMenu getPopupMenu() {
		if (null == popupMenu)
			popupMenu = new TablePopupMenu(this);
		return popupMenu;
	}

	public JTable getTable() {
		if (null == table) {
			// initialize table
			this.table = new JTable();
			this.table.setName(this.getClass().getName() + ".table");
			this.table.setFillsViewportHeight(true);
			this.table.setShowGrid(false);
			this.table.setCellSelectionEnabled(true);
			this.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
			this.table.setModel(this.getTableModel());
			// table double-click handler
			this.table.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent e) {
					if (MouseEvent.BUTTON1 != e.getButton())
						return;
					if (e.getClickCount() < 2)
						return;
					File file = getSelectedFile();
					if (null == file || false == file.exists() || false == file.isDirectory())
						return;
					setDirectory(file, true);
				}
			});
			// setup column width, renderer, etc
			TableCellRenderer[] renderers = new TableCellRenderer[] { new FileNameRenderer(), new SizeRenderer(), DefaultRenderer.getInstance(),
					new DateRenderer(), DefaultRenderer.getInstance() };
			int[] cellWidth = { 225, 85, 125, 150, 85 };
			TableColumnModel model = this.table.getColumnModel();
			for (int i = 0; i < renderers.length; i++) {
				TableColumn column = model.getColumn(i);
				column.setPreferredWidth(cellWidth[i]);
				if (null != renderers[i])
					column.setCellRenderer(renderers[i]);
			}
			table.getColumnModel().setColumnMargin(5);
			// add sorter
			TableRowSorter<FileTableModel> sorter = null;
			sorter = new TableRowSorter<FileTableModel>(getTableModel());
			sorter.setComparator(0, Comparators.newComparator(new FileNameComparator()));
			sorter.setComparator(1, Comparators.newComparator(new FileSizeComparator()));
			sorter.setSortKeys(Collections.singletonList(new SortKey(0, SortOrder.ASCENDING)));
			table.setRowSorter(sorter);
			// set popup menu
			table.setComponentPopupMenu(this.getPopupMenu());
			// table header popup
			TableHelper.test(table);
		}
		return this.table;
	}

	public FileTableModel getTableModel() {
		if (null == this.tableModel) {
			this.tableModel = new FileTableModel();
			this.tableModel.setDirectory(this.getDirectory());
		}
		return this.tableModel;
	}

	private void initialize() {
		this.setLayout(new BorderLayout());
		this.add(new JScrollPane(this.getTable()), BorderLayout.CENTER);
		TableHelper.test(table);
	}
}
